home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / lib / mntlib44.zoo / mntlib / fwrite.c < prev    next >
C/C++ Source or Header  |  1993-09-15  |  3KB  |  163 lines

  1. /* from Dale Schumacher's dLibs */
  2.  
  3. /* 5/26/93 sb -- Modified for HSC to account for the possibility that
  4.  * size * count >= 64K.
  5.  */
  6.  
  7. #include <stddef.h>
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <limits.h>
  11. #include <assert.h>
  12. #include <string.h>
  13. #include "lib.h"
  14.  
  15. extern short  __FRW_BIN__;
  16.  
  17. size_t    fwrite(_data, size, count, fp)
  18. const void *_data;
  19. size_t size;
  20. size_t count;
  21. register FILE *fp;
  22. {
  23.     const char *data=_data;
  24. #ifdef __SOZOBON__
  25.     register unsigned long n, m;
  26. #else
  27.     register size_t n, m;
  28. #endif
  29.     register long l = 0;
  30.     long space;
  31.     unsigned int f = fp->_flag;
  32.     const char *restart_buf;
  33.     int have_nl;
  34.     int wrote_cr;
  35.     int line_flush;
  36.  
  37.     if(f & _IORW)
  38.     {
  39.         fp->_flag |= _IOWRT;
  40.         f = (fp->_flag &= ~(_IOREAD | _IOEOF));
  41.     }
  42.  
  43.     if(!(f & _IOWRT)            /* not opened for write? */
  44.     || (f & (_IOERR | _IOEOF)))        /* error/eof conditions? */
  45.         return(0);
  46.  
  47.     assert ((data != NULL));
  48.     assert ((size != 0));
  49. #ifdef __SOZOBON__
  50.     n =  (unsigned long)count * size;
  51.     assert ( n <= (unsigned_long)LONG_MAX);  /* otherwise impl will not work */
  52. #else
  53.     n =  count * size;
  54.     assert ( n <= (size_t)LONG_MAX);  /* otherwise impl will not work */
  55. #endif
  56.  
  57.     if( (f&_IOBIN) || __FRW_BIN__ ) {
  58.       space = fp->_bsiz - fp->_cnt;
  59.       while(n > 0)
  60.       {
  61.           m = (n > space)? space: n;
  62. #ifdef __SOZOBON__
  63.           _bcopy(data, fp->_ptr, m);
  64. #else
  65.           bcopy(data, fp->_ptr, m);
  66. #endif
  67.           fp->_ptr += m;
  68.           fp->_cnt += m;
  69.           space -= m;
  70.           if(space == 0)
  71.           {
  72.           if(fflush(fp))
  73.               return 0;
  74.           space = fp->_bsiz;
  75.           if(f & _IORW)
  76.               fp->_flag |= _IOWRT; /* fflush resets this */
  77.           }
  78.           l += m;
  79.           data += m;
  80.           n -= m;
  81.           if(n < space)
  82.           continue;
  83.           if((m = _write(fp->_file, data, (unsigned long)n )) != (long)n)
  84.           {
  85.           fp->_flag |= _IOERR;
  86.           return 0;
  87.           }
  88.           l += m;
  89.           break;
  90.       }
  91.     } else {
  92.       have_nl=1;
  93.       wrote_cr=0;
  94.       line_flush=0;
  95.       /* this relies on having at least one byte buffer,
  96.          otherwise we'll hang up when trying to write CRLF */
  97.       while(n > 0) {
  98.           space = fp->_bsiz - fp->_cnt;
  99.           restart_buf=data;
  100.           while( space>0 && n>0 ) {
  101.         if( *data=='\n' ) {
  102.           if( !wrote_cr ) {
  103.             if( f&_IOLBF ) line_flush=1;
  104.             *fp->_ptr++='\r';
  105.             wrote_cr=1;
  106.             have_nl=1;
  107.                 l--;    /* compensate for the increment below */
  108.           } else {
  109.             *fp->_ptr++='\n';
  110.             data++;
  111.             wrote_cr=0;
  112.             n--;
  113.           }
  114.         } else {
  115.           *fp->_ptr++=*data++;
  116.           n--;
  117.         }
  118.         space--;
  119.         fp->_cnt++;
  120.         l++;
  121.           }
  122.  
  123.           if( space==0 ) {
  124.         if( have_nl ) {
  125.           if(fflush(fp))
  126.               return 0;
  127.           if(f & _IORW)
  128.               fp->_flag |= _IOWRT; /* fflush resets this */
  129.           have_nl=0;
  130.         } else {
  131.         /* this will probably happen in nonbuffered mode only:
  132.            try to write as much data in one go as possible */
  133.           fp->_cnt=0;
  134.           fp->_ptr=fp->_base;
  135.           while( n && *data!='\n' ) {
  136.             n--;
  137.             data++;
  138.           }
  139.           if( (m = _write(fp->_file, restart_buf, data - restart_buf))
  140.               != data - restart_buf) {
  141.             fp->_flag |= _IOERR;
  142.             return 0;
  143.           }
  144.           l += (m - 1); /* we already counted one character, before
  145.                  * decrementing 'space' to zero */
  146.         }
  147.           }
  148.       } /* while */
  149.       if( line_flush ) {
  150.          if(fflush(fp))
  151.          return 0;
  152.          if(f & _IORW)
  153.          fp->_flag |= _IOWRT; /* fflush resets this */
  154.       }
  155.     }
  156.  
  157. #ifdef __SOZOBON
  158.     return((l > 0) ? ((size_t)((unsigned long)l / size)) : 0);
  159. #else
  160.     return((l > 0) ? ((size_t)l / size) : 0);
  161. #endif
  162. }
  163.